#include <qmainwindow.h>
#include <qframe.h>
#include <qlabel.h>
#include <qtablewidget.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <QHBoxLayout>
#include <qspinbox.h>
#include <QDoubleSpinBox>
#include <QMap>
#include <QTimer>
#include <QThread>
#include <mutex>
#include <thread>
#ifdef _WINDOWS
#include <ControlCAN.h>
#else
#include <controlcan.h>
#endif

#include "canthread.h"
#include "worker.h"

class MainWindow :public QMainWindow {
	Q_OBJECT
public:
	enum eTimerMode {
		None,
		modeStart,
		modeCycle,
		modeDebug
	};

	MainWindow(QWidget* parent = nullptr);
	~MainWindow();

	void initWindow();

	void clearQueue();
	int sendData(int channel, const CANThread::CanData& data);
	int waitForResp(int channel, UINT id, CANThread::CanData& respData, size_t timeout);
	int sendAndWaitForResp(int channel, const CANThread::CanData& data, CANThread::CanData& retData);
private:
	void startTimer(int interval, eTimerMode mode = eTimerMode::None);
	void stopTimer();

private:
	// for start part:
	void sendStartCmd();
	void sendStopCmd();
	double x102Anal(const CANThread::CanData& d);
	bool waitForX102Counter02(int timeout, CANThread::CanData& canData);;
	bool waitForX102(int timeout, CANThread::CanData& canData);
	int starterDealer();
	int debugDealer();

	// for cycle:
	int cycleDealer();

public slots:
	void onBtnInitClicked();
	void onBtnStartClicked();
	void onBtnExportClicked();
	//void onBtnSaveClicked();
	void onBtnStopClicked();
	void onBtnSelectPathClicked();
	void onTimeout();

	//void startThread();
	//void handleProgress(int percent);
	//void handleResult(int result);
	//void stopThread();

signals:
	void startWork();

private:
	struct {
		QWidget* wCenter;
		QHBoxLayout* topLO;
		QFrame* rFrame, * lFrame, * midFrame;
		QVBoxLayout* rFrameLO, * lFrameLO, * midFrameLO;
		QPushButton* btnInit, * btnStart, * btnExport, * btnSave, * btnSelectPath;
		QTableWidget* table;
		QLabel* lblInit, * lblStart, * lblSetting, * lblExport, * lblShowAngle, * lblMsg;
		QLabel* lblMotorPair, * lblRotatePair;
		QHBoxLayout* exportLO;
		QLabel* lblSave, * lblPath;
		QSpinBox* spMotorPair, * spRotatePair;
		QDoubleSpinBox* dspAngle;
		QHBoxLayout* motorPairLO, * rotatePairLO;

		QPushButton* btnStop;
	} ui;

	QString exportPath;
	CANThread* canThread;
	bool mainStop;
	QMap<UINT, int> idMap;

	QMutex mutex;
	QQueue <CANThread::CanData> qCan0, qCan1;
	QThread* m_thread;
	Worker* worker;

	struct {
		QElapsedTimer els;
		QTimer canTimer;
		qint64 currentInterval;
		eTimerMode timerMode;
		QMap<eTimerMode, std::function<int(int)>> timerFunc;
	} timerVars;

	// for start command:
	struct {
		double modNumber;
		QElapsedTimer etimer;
		std::vector<double> arr;
	} startVars;
};
